﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using StructureMap;
using WebFormsMvp.Contrib.Data.Services;
using WebFormsMvp.Contrib.Presenters;
using WebFormsMvp.Contrib.Views;

namespace WebFormsMvp.Contrib.StructureMap.Tests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class StructureMapPresenterFactortyTests
    {
        [TestMethod]
        public void Instance_Of_Correct_Type()
        {
            //Arrange
            IAuthenticationView view = MockRepository.GenerateMock<IAuthenticationView>();

            var container = new Container(x => x.ForRequestedType<IAuthenticationService>().TheDefault.Is.Object(MockRepository.GenerateMock<IAuthenticationService>()));
            var factory = new StructureMapPresenterFactory(container);

            var presenter = factory.Create(typeof(AuthenticationPresenter), typeof(IAuthenticationView), view);
            //Act

            //Assert
            Assert.IsInstanceOfType(presenter, typeof(AuthenticationPresenter));
            Assert.AreSame(((AuthenticationPresenter)presenter).View, view);
        }

        [TestMethod]
        public void Multiple_Presenters_Are_Unique()
        {
            //Arrange
            var view = MockRepository.GenerateMock<IAuthenticationView>();
            
            var container = new Container(x => x.ForRequestedType<IAuthenticationService>().TheDefault.Is.Object(MockRepository.GenerateMock<IAuthenticationService>()));
            var factory = new StructureMapPresenterFactory(container);

            var view2 = MockRepository.GenerateMock<IAuthenticationView>();

            var p1 = (CustomAuthenticationPresenter)factory.Create(typeof(CustomAuthenticationPresenter), typeof(IAuthenticationView), view);
            var p2 = (CustomAuthenticationPresenter)factory.Create(typeof(CustomAuthenticationPresenter), typeof(IAuthenticationView), view2);
            //Act

            //Assert
            Assert.AreNotSame(p1, p2);
        }

        [TestMethod]
        public void Presenters_Have_Unique_Views()
        {
            //Arrange
            var view = MockRepository.GenerateMock<IAuthenticationView>();
            
            var container = new Container(x => x.ForRequestedType<IAuthenticationService>().TheDefault.Is.Object(MockRepository.GenerateMock<IAuthenticationService>()));
            var factory = new StructureMapPresenterFactory(container);

            var view2 = MockRepository.GenerateMock<IAuthenticationView>();

            var p1 = (CustomAuthenticationPresenter)factory.Create(typeof(CustomAuthenticationPresenter), typeof(IAuthenticationView), view);
            var p2 = (CustomAuthenticationPresenter)factory.Create(typeof(CustomAuthenticationPresenter), typeof(IAuthenticationView), view2);
            //Act

            //Assert
            Assert.AreNotSame(p1.View, p2.View);
        }
        
        [TestMethod]
        public void Preseters_Share_Service_Only()
        {
            //Arrange
            var view = MockRepository.GenerateMock<IAuthenticationView>();
            
            var container = new Container(x => x.ForRequestedType<IAuthenticationService>().TheDefault.Is.Object(MockRepository.GenerateMock<IAuthenticationService>()));
            var factory = new StructureMapPresenterFactory(container);

            var view2 = MockRepository.GenerateMock<IAuthenticationView>();

            var p1 = (CustomAuthenticationPresenter)factory.Create(typeof(CustomAuthenticationPresenter), typeof(IAuthenticationView), view);
            var p2 = (CustomAuthenticationPresenter)factory.Create(typeof(CustomAuthenticationPresenter), typeof(IAuthenticationView), view2);
            //Act

            //Assert
            Assert.IsNotNull(p1.DataService);
            Assert.IsNotNull(p2.DataService);
            Assert.AreSame(p1.DataService, p2.DataService);
            Assert.AreNotSame(p1.View, p2.View);
        }
    }
}
